AWS Valut と direnv を使い簡単安全にスイッチロールしてみた
ブログ内容
こんにちは、望月です。
AWS Vault 使ってますか?私は最近 PC の入れ替えをしたタイミングで導入してみました。
AWS Vault を利用することでアクセスキー/シークレットキーをキーチェーン等で保存することができるため、安全に AWS CLI などを利用することが出来ます。インストール方法については以下ブログを読んでもらえばサクッと対応できると思います。
AWS Valut と合わせて、今までの環境で利用していた direnv を組み合わせて使ってみたのでここではその方法をまとめたいと思います。direnv はスイッチロールをする際にディレクトリ移動することで一時クレデンシャルを取得・設定することが出来るため、気軽にスイッチロールを行うことが出来ます。direnv については以下ブログをご確認ください。
やってみた
前提
- AWS Vault をインストール済み
- バージョン
6.6.0-Homebrew
を利用
- バージョン
- direnv をインストール済み
- バージョン
2.32.2
を利用
- バージョン
- zsh
5.9
を利用
どれも Homebrew を利用することで簡単にインストールすることが出来ます。
Profile の設定内容
スイッチロール先の情報を ~/.aws/config
に記載します。direnv ではカレントディレクトリ名を利用し、スイッチロールするので Profile 名とカレントディレクトリ名を合わせる必要があります。ここでは [profile test]
という形で Profile 名を設定します。
[profile test] include_profile=... role_arn=... ...
設定後に aws-vault ls
コマンドを実施し、Profile test が表示されるようになります。
% aws-vault ls Profile Credentials Sessions ======= =========== ======== ... test - - ...
.envrc の作成
test
ディレクトリを作成し test
ディレクトリ配下に以下のように .envrc
を作成します。
PROFILE_NAME=$(basename $(pwd)) export AWS_ACCESS_KEY_ID=$(aws-vault exec ${PROFILE_NAME} -j | jq -r '.AccessKeyId') export AWS_SECRET_ACCESS_KEY=$(aws-vault exec ${PROFILE_NAME} -j | jq -r '.SecretAccessKey') export AWS_SESSION_TOKEN=$(aws-vault exec ${PROFILE_NAME} -j | jq -r '.SessionToken') # PROMPT export PROMPT="%F{red}[$(aws sts get-caller-identity | jq -r '.Account')]%f ${PROMPT}"
実行している内容については以下説明していきます。
PROFILE_NAME=$(basename $(pwd))
- 変数
PROFILE_NAME
にカレントディレクトリ名を設定します
- 変数
export AWS_ACCESS_KEY_ID=$(aws-vault exec ${PROFILE_NAME} -j | jq -r '.AccessKeyId')
- アクセスキーを取得し、変数
AWS_ACCESS_KEY_ID
に設定します
- アクセスキーを取得し、変数
export AWS_SECRET_ACCESS_KEY=$(aws-vault exec ${PROFILE_NAME} -j | jq -r '.SecretAccessKey')
- シークレットキーを取得し、変数
AWS_SECRET_ACCESS_KEY
に設定します
- シークレットキーを取得し、変数
export AWS_SESSION_TOKEN=$(aws-vault exec ${PROFILE_NAME} -j | jq -r '.SessionToken')
- セッショントークンを取得し、変数
AWS_SESSION_TOKEN
に設定します
- セッショントークンを取得し、変数
aws-vault exec のヘルプを確認すると -j
オプションを使うことで、クレデンシャル情報が JSON で受け取ることが出来ることが分かります。そのため aws-vault exec test -j
コマンドを実行し、一時クレデンシャルを取得し各変数に設定していきます。
% aws-vault exec --help usage: aws-vault exec [<flags>] <profile> [<cmd>] [<args>...] Executes a command with AWS credentials in the environment Flags: --help Show context-sensitive help (also try --help-long and --help-man). --version Show application version. --debug Show debugging output --backend=keychain Secret backend to use [keychain pass file] ($AWS_VAULT_BACKEND) --prompt=terminal Prompt driver to use [kdialog osascript pass terminal ykman zenity] ($AWS_VAULT_PROMPT) --keychain="aws-vault" Name of macOS keychain to use, if it doesn't exist it will be created ($AWS_VAULT_KEYCHAIN_NAME) --secret-service-collection="awsvault" Name of secret-service collection to use, if it doesn't exist it will be created ($AWS_VAULT_SECRET_SERVICE_COLLECTION_NAME) --pass-dir=PASS-DIR Pass password store directory ($AWS_VAULT_PASS_PASSWORD_STORE_DIR) --pass-cmd=PASS-CMD Name of the pass executable ($AWS_VAULT_PASS_CMD) --pass-prefix=PASS-PREFIX Prefix to prepend to the item path stored in pass ($AWS_VAULT_PASS_PREFIX) --file-dir="~/.awsvault/keys/" Directory for the "file" password store ($AWS_VAULT_FILE_DIR) -d, --duration=DURATION Duration of the temporary or assume-role session. Defaults to 1h -n, --no-session Skip creating STS session with GetSessionToken --region=REGION The AWS region -t, --mfa-token=MFA-TOKEN The MFA token to use -j, --json Output credentials in JSON that can be used by credential_process -s, --server Alias for --ec2-server. Run a EC2 metadata server in the background for credentials --ec2-server Run a EC2 metadata server in the background for credentials --ecs-server Run a ECS credential server in the background for credentials (the SDK or app must support AWS_CONTAINER_CREDENTIALS_FULL_URI) --lazy When using --ecs-server, lazily fetch credentials --stdout Print the SSO link to the terminal without automatically opening the browser Args: <profile> Name of the profile [<cmd>] Command to execute, defaults to $SHELL [<args>] Command arguments
おまけ
最後に export PROMPT="%F{red}[$(aws sts get-caller-identity | jq -r '.Account')]%f ${PROMPT}"
を実行していますが、こちらはプロンプトに AWS アカウント ID を表示するコマンドになります。カレントディレクトリ名で接続しているアカウントは分かりますが、念のため AWS アカウント ID を表示することでなんとなくいつも見てる ID と違う…みたいな予防を想定しています。
[123456789012] 10:00 @mochizuki.yuta test %
まとめ
AWS Vault と direnv を利用し、簡単にスイッチロールを行う環境を作ることができました。複数の AWS アカウントを利用しつつ、セキュアに AWS を使いたいといった場合に AWS Vault と direnv を利用するのはいかがでしょうか。